#ifndef BIG_BUFFER_H
#define BIG_BUFFER_H

#include <unistd.h>
#include <string>

#include <vector>
#include <algorithm>
#include "types.h"

class BigBuffer
{
private:
    static const unsigned int chunkSize = BLOCKSIZE;
    class ChunkWrapper;
    typedef std::vector<ChunkWrapper> chunks_t;
    struct CallBackStruct
    {
        size_t pos;
        const BigBuffer *buf;
        time_t mtime;
    };
    chunks_t chunks;
    inline static size_t chunksCount(size_t size)
    {
        return (size + chunkSize - 1) / chunkSize;
    }
    inline static size_t chunkNumber(size_t offset)
    {
        return offset / chunkSize;
    }
    inline static unsigned int chunkOffset(size_t offset)
    {
        return offset % chunkSize;
    }

public:
    size_t len;
    BigBuffer();
    BigBuffer(size_t length);
    void truncate(size_t offset);
    ~BigBuffer();
    int open_disk_files(const char *real_name, std::vector<int>& fd_vector) const;
    int read(char *buf, size_t size, size_t offset) const;
    int file_read(char *buf, size_t size, size_t offset, const char *real_name, uint64_t real_file_size) const;
    int vsphere_read(char *buf, size_t size, size_t offset, uint64_t real_file_size, std::vector<int> &real_file_vector, const int store_file, const std::unordered_map<int, std::vector<DataSegment>>& cache) const;
    int fsphere_read(char *buf, size_t size, size_t offset, const char *real_name, uint64_t real_file_size, const char *store_name) const;
    int write(const char *buf, size_t size, size_t offset);
    int file_write(const char *buf, size_t size, size_t offset, const char *real_name, uint64_t real_file_size);
    int vsphere_write(const char *buf, size_t size, size_t offset, uint64_t real_file_size, std::vector<int> &real_file_vector, const int store_file, const std::unordered_map<int, std::vector<DataSegment>>& cache);
    int fsphere_write(const char *buf, size_t size, size_t offset, const char *real_name, uint64_t real_file_size, const char *store_name);
};
#endif
